﻿//Copyright 2010 http://tv4home.codeplex.com
//This file is part of TV4Home.Client.TVViewer.
//TV4Home.Client.TVViewer is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.
//TV4Home.Client.TVViewer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//You should have received a copy of the GNU Lesser General Public License along with TV4Home.Client.TVViewer. If not, see http://www.gnu.org/licenses/.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TV4Home.Server.TVEInteractionLibrary.Interfaces;
using System.ServiceModel;
using System.Windows.Threading;
using System.Threading;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.ComponentModel;


namespace TV4Home.Client.Desktop.TVViewer.Pages
{
    /// <summary>
    /// Interaktionslogik für TVViewer.xaml
    /// </summary>
    public partial class TVViewer : Page
    {
        #region Attribute

        private ITVEInteraction tvWebClient = null;
        private BackgroundWorker channelWorker = new BackgroundWorker();
        private BackgroundWorker playChannelWorker = new BackgroundWorker();

        public static System.Timers.Timer timer = new System.Timers.Timer();
        public delegate void ChangeVisibilityDelegate();
        WebChannelBasic selectedChannel;

        string UserNameStream1;
        string UserNameStream2;

        //public float MediaPosition { get { return myVlcControl.Position; } }
        public string Url { get; set; }
        #endregion

        #region Constructor / destructor

        public TVViewer()
        {
            InitializeComponent();


            UserNameStream1 = "TVViewerStream1";
            UserNameStream2 = "TVViewerStream2";

            InitializeChannelData();

        }
        #endregion
        #region Channel
        private void InitializeChannelData()
        {
            ConnectToService();
            InitializeBackgroundWorker();
            if (!String.IsNullOrEmpty(Properties.Settings.Default.ServerName))
            {
                FetchChannelData();
            }
        }
        public void FetchChannelData()
        {
            Properties.Settings.Default.Reload();
            if (tvWebClient == null)
            {
                ConnectToService();
            }
            channelWorker.RunWorkerAsync();
        }
        private void InitializeBackgroundWorker()
        {
            channelWorker.DoWork += new DoWorkEventHandler(channelWorker_DoWork);
            channelWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(channelWorker_RunWorkerCompleted);
            playChannelWorker.DoWork += new DoWorkEventHandler(playChannelWorker_DoWork);

        }

        void playChannelWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (selectedChannel != null)
            {
                PlayChannel(selectedChannel);
            }
        }
        void channelWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (e.Result != null)
            {
                List<WebChannelBasic> channelList = e.Result as List<WebChannelBasic>;
                lbChannels.ItemsSource = channelList;
            }
        }
        void channelWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (tvWebClient != null)
            {
                e.Result = tvWebClient.GetChannelsBasic(Properties.Settings.Default.DefaultGroup);
            }
        }
        #endregion


        #region Page


        private void Page_Unloaded(object sender, RoutedEventArgs e)
        {
            StopTimeshifting();
        }
        #endregion

        #region UIEventHandler
        private void lbChannels_Selected(object sender, RoutedEventArgs e)
        {
            if (e.OriginalSource is ListBoxItem)
            {
                if (((ListBoxItem)e.OriginalSource).Content is WebChannelBasic)
                {
                    WebChannelBasic channel = ((ListBoxItem)e.OriginalSource).Content as WebChannelBasic;
                    if (channel != null)
                    {
                  
                        selectedChannel = channel;
                        playChannelWorker.RunWorkerAsync();
                    }
                }
            }
        }
        #endregion

        #region ServiceConnection


        private void PlayChannel(WebChannelBasic channel)
        {
            try
            {

                tvWebClient.CancelCurrentTimeShifting(UserNameStream1);
                bool str = tvWebClient.SwitchTVServerToChannelAndInitStream(UserNameStream1, channel.IdChannel, "Android HQ");
                //string url = tvWebClient.SwitchTVServerToChannelAndGetStreamingUrl(UserNameStream1, channel.IdChannel);
                //bool str = false;
                //meStream1.Source = new Uri( url.Replace(":554",""));
                //meStream1.Play();

                try
                {
                    if (str == true)
                    {
                        this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(delegate()
                         {
                             meStream1.Source = new Uri(String.Format("http://{0}:4321/TV4Home.Server.CoreService/TVEInteractionService/stream/RetrieveStream?identifier={1}", Properties.Settings.Default.ServerName, UserNameStream1));
                             meStream1.Play();
                         }));

                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Inner Exception @ Play: " + ex.ToString());
                }

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }



        public void StopTimeshifting()
        {
            try
            {
                tvWebClient.CancelCurrentTimeShifting(UserNameStream1);
                tvWebClient.CancelCurrentTimeShifting(UserNameStream2);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void ConnectToService()
        {
            //Connects to the tv4home webservice 
            try
            {
                tvWebClient = Connect();
            }
            catch (Exception ex)
            {
                //if connection is not possible ask whether it retry or not
                string sMessageBoxText = "Couldn't connect. Try again?";
                string sCaption = "QuickEPG";

                MessageBoxButton btnMessageBox = MessageBoxButton.YesNo;
                MessageBoxImage icnMessageBox = MessageBoxImage.Warning;

                MessageBoxResult rsltMessageBox = MessageBox.Show(sMessageBoxText, sCaption, btnMessageBox, icnMessageBox);
                // Process message box results
                switch (rsltMessageBox)
                {

                    case MessageBoxResult.Yes:
                        ConnectToService();
                        break;
                    case MessageBoxResult.No:
                        MessageBox.Show(ex.ToString());
                        break;
                }
            }

        }
        private ITVEInteraction Connect()
        {
            if (!String.IsNullOrEmpty(Properties.Settings.Default.ServerName))
            {
                switch (Properties.Settings.Default.IsIntranet)
                {
                    case true:
                        return ChannelFactory<ITVEInteraction>.CreateChannel(new BasicHttpBinding() { MaxReceivedMessageSize = 10000000 }, new EndpointAddress(String.Format(Properties.Settings.Default.IntranetUrl, Properties.Settings.Default.ServerName)));
                    case false:
                        return ChannelFactory<ITVEInteraction>.CreateChannel(new BasicHttpBinding() { MaxReceivedMessageSize = 10000000 }, new EndpointAddress(String.Format(Properties.Settings.Default.InternetUrl, Properties.Settings.Default.ServerName)));
                }
            }

            return null;
        }

        #endregion


        #region methods to hide player controls
        private void meStream1_MouseMove(object sender, MouseEventArgs e)
        {

        }

        public void MouseMoved()
        {
            brdCtrlBtn.Visibility = System.Windows.Visibility.Visible;
            timer.Start();
        }
        void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {

            brdCtrlBtn.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
        new ChangeVisibilityDelegate(ChangeCtrlBtnVisibility));

            timer.Stop();
        }
        private void ChangeCtrlBtnVisibility()
        {
            switch (brdCtrlBtn.Visibility)
            {
                case System.Windows.Visibility.Visible:
                    brdCtrlBtn.Visibility = Visibility.Hidden;
                    break;
                case System.Windows.Visibility.Hidden:
                    brdCtrlBtn.Visibility = Visibility.Visible;
                    break;

            }

        }
        #endregion

    }
}
